home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 421_01 / comsim.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-16  |  8.6 KB  |  503 lines

  1. // "COMMANCHE"
  2.  
  3. // INCLUDES
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <math.h>
  8.  
  9. #include "template.h"
  10. #include "comsim.h"
  11. #include "vx.h"
  12. #include "timer.h"
  13.  
  14. // EXTERNALS
  15. extern timer_C timer;
  16. extern vx_C vx;
  17. extern byte *keypressed;
  18.  
  19. // GLOBAL VARS
  20.  
  21. byte *dataseg1,*data_ptr;
  22. char sincurve1[256],sincurve2[256];
  23. byte farmap=0;
  24. float maxh;
  25. int lookheredown=233;
  26.  
  27. // FUNCTIONS
  28.  
  29. // SETCOLORS
  30.  
  31. void setcolors(void)
  32. {
  33.   int qw=0;
  34.   for (int plan=0; plan<4; plan++)
  35.   for (int teller=0; teller<64; teller++)
  36.     {
  37.     float r,g,b;
  38.     switch(plan)
  39.     {
  40.       case 0:   r=teller/2;
  41.         g=(3*teller)/4;
  42.         b=teller/5;
  43.         break;
  44.       case 1:    r=(teller*7)/7;
  45.         g=(teller*7)/8;
  46.         b=(teller*22)/32;
  47.         break;
  48.       case 2:   r=teller/4;
  49.         g=teller/4;
  50.         b=teller;
  51.         break;
  52.       case 3:    r=g=b=(teller*4)/5;
  53.         break;
  54.     }
  55.     vx.setrgb(teller+64*plan,r,g,b);
  56.   }
  57. }
  58.  
  59. // MAKEVRAM
  60.  
  61. void makevram()
  62. {
  63.   vx.blockfill(0,10,0);
  64.   vx.blockfill(10,65535,0);
  65.   vx.setoffset(8192);
  66.   for (float teller=0; teller<256; teller++)
  67.   {
  68.     float val2,val=sin(teller*3.14159265/128);
  69.     sincurve1[teller]=val*127;
  70.     sincurve2[teller]=val*val*val*127;
  71.     }
  72.   for (int ha=0; ha<32; ha++)
  73.   {
  74.     float haz=1.05-4.0*ha/125.0;
  75.     fit ((float)0,haz,(float)1);
  76.     for (int plan=0; plan<4; plan++)
  77.       for (int teller=0; teller<256; teller++)
  78.       {
  79.     int base=64*(teller/64);
  80.     int color=teller&63;
  81.     if (color==10)
  82.     {
  83.       base=128;
  84.       color=20+teller/26;
  85.     }
  86.     color+=random(RANDOM);
  87.     fit(0,color,63);
  88.     vx.writepixel(ha*256+teller,plan,haz*(color/1.5+21)+base);
  89.       }
  90.   }
  91. #define BIG 40
  92.   for (int c=0; c<80; c++)
  93.   {
  94.     int vin=BIG*(c/BIG);
  95.     int sm=c%BIG;
  96.     if (sm&1)
  97.       sm=BIG-1-sm/2;
  98.     else
  99.       sm=sm/2;
  100.     int no=vin+sm;
  101.     data_ptr[c+ORDER]=no;
  102.   }
  103. }
  104.  
  105. // MAKEMAPLINE
  106.  
  107. void makemapline(byte qteller)
  108. {
  109.     static int magic1=0;
  110.     static int slide=0;
  111.     slide++;
  112.     magic1++;
  113.     static int bigfac=0;
  114.     float last;
  115.     last=0;
  116.     static int flow;
  117.     static byte no1=random(256),no2=random(256),no3=random(256),
  118.                 no4=random(256),no5=random(256),no6=random(256);
  119.  
  120.     no3=no5+87;
  121.     no4=49+no6;
  122.     no1+=1;
  123.     no2+=2;
  124.     no5+=2;
  125.     no6+=3;
  126.     int adresse=qteller+MAPDATA;
  127.     for (int teller=0; teller<MAPX; teller++)
  128.     {
  129.         int temp=sincurve1[no1]+sincurve2[no2]+
  130.              sincurve1[no3]+sincurve2[no4];
  131.         int sgn=1;
  132.     if (temp<0)
  133.       temp*=-1;
  134.     temp>>=1;
  135.     word temp2=temp*bigfac;
  136.     temp2>>=10;
  137.  
  138.     no3+=10;
  139.     no4-=6;
  140.  
  141.     if (temp2>ICE)
  142.       temp2+=192;
  143.     if (temp2<=LAKE)
  144.       temp2=10+64*random(4);
  145.     else
  146.     if (temp2<BEACH)
  147.       temp2+=64;
  148.     data_ptr[adresse]=temp2;
  149.     adresse+=MAPY;
  150.   }
  151.   flow++;
  152.   if (bigfac || (!lookheredown))
  153.     bigfac=max(50,bigfac+1);
  154.   if (bigfac>255)
  155.     bigfac=255;
  156. }
  157.  
  158. // MAKELOOKUP
  159.  
  160. void makelookup(void)
  161. {
  162.   float v,s;
  163.   for (int y=0; y<MAPY/4; y++)
  164.   for (int z=0; z<64; z++)
  165.   {
  166.         v=atan(4.0*y/(HEIGHT-z));
  167.     v-=DOWNVIEW;
  168.     s=sin(v);
  169.     int hei=CENTER+WIDTH*s;
  170.     if (hei<0)
  171.       hei=0;
  172.     data_ptr[256*z+192+y]=hei;
  173.   }
  174. }
  175.  
  176. // MAKEMAPDATA
  177.  
  178. void makemapdata(void)
  179. {
  180.   for (int teller=0; teller<MAPY; teller++)
  181.     makemapline(teller);
  182. }
  183.  
  184. // MAKEXFAC
  185.  
  186. void makexfac()
  187. {
  188.   for (int teller=0; teller<80; teller++)
  189.   {
  190.     float real=teller*MAPX/80.0;
  191.     int xdiff=LENS*(real-MAPX/2);
  192.     float temp=(float)xdiff/MAPY;
  193.     if (temp<0)
  194.       temp++;
  195.     temp*=256;
  196.     byte itemp=(temp+0.5);
  197.     data_ptr[XFAC+teller]=itemp;
  198.   }
  199. }
  200.  
  201. // MAKEORIGMAX
  202.  
  203. void makeorigmax(void)
  204. {
  205.   for (int teller=0; teller<160; teller++)
  206.     data_ptr[ORIGMAX+teller]=0;
  207. }
  208.  
  209.  
  210.  
  211. // SHOWMAP
  212.  
  213. void showmap(void)
  214. {
  215.   for (int x=0; x<MAPX; x++)
  216.   for (int y=0; y<MAPY; y++)
  217.   {
  218.     vx.writepixel(x/4+80*y,x&3,data_ptr[(long)MAPDATA+(long)256*x+y]);
  219.   }
  220. }
  221.  
  222. // DRAW
  223.  
  224. void draw(word vrampos,byte down)
  225. {
  226.   vrampos+=233*80;
  227.   asm push ds
  228.   asm pusha
  229.   int localfarmap=farmap;
  230.   byte br0k,maxy;
  231.   word xcount=0;
  232.  
  233.   asm mov dx,GC_INDEX
  234.   asm mov ax,BIT_MASK
  235.   asm out dx,ax
  236.  
  237.   asm mov dx,SC_INDEX+1
  238.   asm mov al,0x0f
  239.   asm out dx,al
  240.  
  241.   asm mov ax,0xa000
  242.   asm mov es,ax
  243.  
  244.   asm xor dl,dl
  245.   asm lds si,data_ptr        // ds=seg data_ptr
  246.  
  247. nextrow:
  248.   asm mov dx,xcount
  249.   asm mov br0k,dh
  250.   asm mov si,dx
  251.   asm mov di,dx
  252.  
  253.   asm add di,vrampos
  254.   asm mov bx,localfarmap
  255.   asm add bx,MAPDATA+256*(MAPX/2)
  256.                 // bx=bmp-pos
  257.   asm mov cl,[si+XFAC]        // cl=pluss
  258.   asm mov ah,down
  259.   asm mov maxy,ah
  260.     asm mov dl,192
  261. countup:
  262.  
  263.     asm mov al,[bx]
  264.     asm mov dh,al
  265.     asm and dh,63
  266.     asm xchg dx,di
  267.     asm mov ah,[di]
  268.     asm xchg dx,di
  269.  
  270.     asm cmp ah,maxy
  271.     asm jbe nothingnew
  272.   asm mov dh,ah
  273.   asm sub dh,maxy
  274.   asm mov maxy,ah
  275. #if HAZE
  276.   asm mov ah,dl
  277.   asm and ah,63
  278.   asm shr ah,HAZE
  279. #else
  280.   asm xor ah,ah
  281. #endif
  282.   asm mov si,ax
  283. #if FUZZY
  284. moveup:
  285.   asm mov al,[es:si]
  286.   asm xor si,FUZZY
  287. #else
  288.   asm mov al,[es:si]
  289.   moveup:
  290. #endif
  291.   asm mov [es:di],al
  292.   asm sub di,80
  293.   asm dec dh
  294.   asm jnz moveup
  295.  
  296. nothingnew:
  297.   asm inc bl
  298.   asm add br0k,cl
  299.   asm adc bh,0
  300.   asm dec bh
  301.   asm inc dl
  302.   asm jnz countup
  303.  
  304.   asm mov dh,maxy
  305.   asm mov si,xcount
  306.   asm sub dh,[si+LASTTOP]
  307.   asm add [si+LASTTOP],dh
  308.   asm cmp dh,210
  309.   asm jb lower
  310.   asm mov dl,[es:-1]
  311. clearup:
  312.   asm mov [es:di],dl
  313.   asm sub di,80
  314.   asm inc dh
  315.   asm jnz clearup
  316. lower:
  317. // OK! NOW TO THE RIGHT SIDE: //
  318.   asm add xcount,40
  319. nextrow2:
  320.   asm mov dx,xcount
  321.   asm mov br0k,dh
  322.   asm mov si,dx
  323.   asm mov di,dx
  324.  
  325.   asm add di,vrampos
  326.   asm mov bx,localfarmap
  327.   asm add bx,MAPDATA+256*(MAPX/2)
  328.     asm mov cl,[si+XFAC]
  329.     asm mov ah,down
  330.     asm mov maxy,ah
  331.     asm mov dl,192
  332. countup2:
  333.     asm mov al,[bx]
  334.     asm mov dh,al
  335.     asm and dh,63
  336.     asm xchg dx,di
  337.     asm mov ah,[di]
  338.     asm xchg dx,di
  339.  
  340.   asm cmp ah,maxy
  341.   asm jbe nothingnew2
  342.   asm mov dh,ah
  343.   asm sub dh,maxy
  344.   asm mov maxy,ah
  345. #if HAZE
  346.   asm mov ah,dl
  347.   asm and ah,63
  348.   asm shr ah,HAZE
  349. #else
  350.   asm xor ah,ah
  351. #endif
  352.   asm mov si,ax
  353. #if FUZZY
  354. moveup2:
  355.   asm mov al,[es:si]
  356.   asm xor si,FUZZY
  357. #else
  358.   asm mov al,[es:si]
  359. moveup2:
  360. #endif
  361.   asm mov [es:di],al
  362.   asm sub di,80
  363.   asm dec dh
  364.   asm jnz moveup2
  365.  
  366. nothingnew2:
  367.   asm inc bl
  368.   asm add br0k,cl
  369.   asm adc bh,0
  370.   asm inc dl
  371.   asm jnz countup2
  372.   asm mov dh,maxy
  373.     asm mov si,xcount
  374.   asm sub dh,[si+LASTTOP]
  375.   asm add [si+LASTTOP],dh
  376.   asm cmp dh,215
  377.   asm jb lower2
  378.   asm mov dl,[es:-1]
  379. clearup2:
  380.   asm mov [es:di],dl
  381.   asm sub di,80
  382.   asm inc dh
  383.   asm jnz clearup2
  384.  
  385. lower2:
  386.  
  387.   asm sub xcount,39
  388.   asm cmp xcount,40
  389.   asm je row79done
  390.   asm jmp nextrow
  391. row79done:
  392.  
  393.   asm mov dx,GC_INDEX+1
  394.   asm mov al,0xff
  395.   asm out dx,al
  396.  
  397.   asm mov  dx,SC_INDEX
  398.     asm mov  al,MAP_MASK
  399.   asm out  dx,al
  400.   asm inc  dx
  401.  
  402.   asm popa
  403.   asm pop ds
  404. }
  405.  
  406. // MEMBLIT
  407.  
  408. void memblit(word from, word to)
  409. {
  410.   asm push ds
  411.   asm cld
  412.   asm lds ax,data_ptr
  413.   asm mov ax,ds
  414.   asm mov es,ax
  415.   asm mov si,from
  416.   asm mov di,to
  417. #ifdef USE32
  418.   asm mov cx,20
  419.   asm rep movsd
  420. #else
  421.   asm mov cx,40
  422.   asm rep movsw
  423. #endif
  424.   asm pop ds
  425. }
  426.  
  427. // COMSIM
  428.  
  429. float comsim(void)
  430. {
  431.   float fps;
  432.   dataseg1=new byte[DATAEND+32];
  433.     data_ptr=(byte *)((long)dataseg1+65532l);
  434.   for (word teller=0; teller<DATAEND; teller++)
  435.     data_ptr[teller]=0;
  436.  
  437.   makevram();
  438.   setcolors();
  439.   makelookup();
  440.   makemapdata();
  441.   makexfac();
  442.   makeorigmax();
  443.     long lastscroll,start,stop,msek,count=0;
  444.   word apos=8192,oldlast=LASTTOP+80;
  445.   int speed=SPEED;
  446.   for (int wind=0; wind<00; wind++)
  447.   {
  448.     makemapline(farmap);
  449.     farmap=(farmap+speed)&255;
  450.   }
  451.   lastscroll=start=timer.readtimer();
  452.   byte down=233,bailout=0,timeroll=0;
  453.   long herenow,gone,timestamp[3];
  454.   timestamp[0]=timestamp[1]=timestamp[2]=start;
  455.   do
  456.   {
  457.     lookheredown=down;
  458.     apos+=19200-256;
  459.     if (apos==-512)
  460.       apos=8192;
  461.     memblit(oldlast,LASTTOP);
  462.     draw(apos,down);
  463.     memblit(LASTTOP,oldlast);
  464.     long now=timer.readtimer();
  465.     do
  466.     {
  467.       herenow=timer.readtimer();
  468.             gone=timer.elapsed(timestamp[timeroll],herenow);
  469.     } while (gone<42);
  470.     timestamp[timeroll++]=herenow;
  471.     if (timeroll==3)
  472.       timeroll=0;
  473.     vx.setoffset(apos);
  474.     if (timer.elapsed(lastscroll,now)>6)
  475.     {
  476.       lastscroll=now;
  477.       if (bailout)
  478.             {
  479.     for (word o=80+LASTTOP; o<320+LASTTOP; o++)
  480.       data_ptr[o]+=2;
  481.     down+=1;
  482.       }
  483.       else
  484.     down-=!!down;
  485.     }
  486.     oldlast+=80;
  487.     if (oldlast==LASTTOP+320)
  488.       oldlast=LASTTOP+80;
  489.     makemapline(farmap);
  490.     farmap=(farmap+speed)&255;
  491.     count++;
  492.     if (keypressed[57] && !(count&7))
  493.       speed*=-1;
  494.     if (keypressed[1])
  495.       bailout=1;
  496.   } while (down<234);
  497.   stop=timer.readtimer();
  498.   msek=timer.elapsed(start,stop);
  499.   delete dataseg1;
  500.   return (1.0*count/(msek/1000.0));
  501. }
  502.  
  503.